package com.eurasia.assignment.service;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.eurasia.assignment.controller.dto.CreateProjectRequest;
import com.eurasia.assignment.controller.dto.ProjectSearchRequest;
import com.eurasia.assignment.domain.Project;
import com.eurasia.assignment.infrastructure.entity.ProjectEntity;
import com.eurasia.assignment.infrastructure.repository.ProjectRepository;

/**
 * 项目服务类
 */
@Service
public class ProjectService {

    private final ProjectRepository projectRepository;

    @Autowired
    public ProjectService(ProjectRepository projectRepository) {
        this.projectRepository = projectRepository;
    }

    /**
     * 创建新项目
     * @param request 项目创建请求
     * @return 创建的项目
     */
    @Transactional
    public Project createProject(CreateProjectRequest request) {
        // 创建项目对象
        Project project = Project.create(
            request.getName(),
            request.getType(),
            request.getCourseId(),
            request.getPoints(),
            request.getCreator()
        );
        
        // 保存到数据库
        var savedProject = projectRepository.save(ProjectEntity.fromDomain(project));

        return savedProject.toDomain();
    }
    
    /**
     * 获取所有项目
     * @return 项目列表
     */
    public List<Project> getAllProjects() {
        return projectRepository.findAll().stream()
                .map(ProjectEntity::toDomain)
                .collect(Collectors.toList());
    }
    
    /**
     * 根据ID获取项目
     * @param id 项目ID
     * @return 项目对象
     */
    public Project getProjectById(Long id) {
        return projectRepository.findById(id)
                .map(ProjectEntity::toDomain)
                .orElseThrow(() -> new IllegalArgumentException("项目不存在：" + id));
    }
    
    /**
     * 分页搜索项目
     * @param searchRequest 搜索条件
     * @param page 页码
     * @param size 每页大小
     * @return 分页结果
     */
    public Page<Project> searchProjectsWithPagination(ProjectSearchRequest searchRequest, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        Page<ProjectEntity> projectPage;
        
        if (StringUtils.hasText(searchRequest.getName()) && StringUtils.hasText(searchRequest.getType())) {
            projectPage = projectRepository.findByNameContainingAndType(
                searchRequest.getName(),
                searchRequest.getType(),
                pageable
            );
        } else if (StringUtils.hasText(searchRequest.getName())) {
            projectPage = projectRepository.findByNameContaining(
                searchRequest.getName(),
                pageable
            );
        } else if (StringUtils.hasText(searchRequest.getType())) {
            projectPage = projectRepository.findByType(
                searchRequest.getType(),
                pageable
            );
        } else {
            projectPage = projectRepository.findAll(pageable);
        }
        
        return projectPage.map(ProjectEntity::toDomain);
    }
    
    /**
     * 删除项目
     * @param id 项目ID
     */
    @Transactional
    public void deleteProject(Long id) {
        if (!projectRepository.existsById(id)) {
            throw new IllegalArgumentException("项目不存在：" + id);
        }
        projectRepository.deleteById(id);
    }
    
    /**
     * 更新项目
     * @param id 项目ID
     * @param projectDetails 项目详情
     * @return 更新后的项目
     */
    @Transactional
    public Project updateProject(Long id, Project projectDetails) {
        ProjectEntity projectEntity = projectRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("项目不存在：" + id));
                
        projectEntity.setName(projectDetails.getName());
        projectEntity.setType(projectDetails.getType());
        projectEntity.setCourseId(projectDetails.getCourseId());
        projectEntity.setStatus(projectDetails.getStatus());
        projectEntity.setPoints(projectDetails.getPoints());
        projectEntity.setCreator(projectDetails.getCreator());
        
        return projectRepository.save(projectEntity).toDomain();
    }
}